<script lang="ts" setup>
  import { FieldRule } from '@arco-design/web-vue';
  import { BehaviorCaptchaReq, getSmsCaptcha } from '@/api/common/captcha';
  import { UserPhoneUpdateReq, updatePhone } from '@/api/system/user-center';
  import { useI18n } from 'vue-i18n';
  import { useUserStore } from '@/store';
  import { encryptByRsa } from '@/utils/encrypt';

  const { proxy } = getCurrentInstance() as any;
  const { t } = useI18n();
  const userStore = useUserStore();
  const formRef = ref();
  const captchaTime = ref(60);
  const captchaTimer = ref();
  const captchaLoading = ref(false);
  const captchaDisable = ref(true);
  const captchaType = ref('blockPuzzle');
  const captchaMode = ref('pop');
  const visible = ref(false);
  const captchaBtnNameKey = ref('userCenter.securitySettings.captcha.get');
  const captchaBtnName = computed(() => t(captchaBtnNameKey.value));

  // 表单数据
  const form = reactive<UserPhoneUpdateReq>({
    newPhone: '',
    captcha: '',
    currentPassword: '',
  });
  // 表单验证规则
  const rules = computed((): Record<string, FieldRule[]> => {
    return {
      newPhone: [
        {
          required: true,
          message: t(
            'userCenter.securitySettings.updatePhone.form.error.required.newPhone',
          ),
        },
        {
          match: /^1[3-9]\d{9}$/,
          message: t(
            'userCenter.securitySettings.updatePhone.form.error.match.newPhone',
          ),
        },
      ],
      captcha: [
        {
          required: true,
          message: t('userCenter.securitySettings.form.error.required.captcha'),
        },
      ],
      currentPassword: [
        {
          required: true,
          message: t(
            'userCenter.securitySettings.updatePhone.form.error.required.currentPassword',
          ),
        },
      ],
    };
  });

  /**
   * 重置验证码
   */
  const resetCaptcha = () => {
    window.clearInterval(captchaTimer.value);
    captchaTime.value = 60;
    captchaBtnNameKey.value = 'userCenter.securitySettings.captcha.get';
    captchaDisable.value = false;
  };

  /**
   * 弹出行为验证码
   */
  const handleOpenBehaviorCaptcha = () => {
    if (captchaLoading.value) return;
    formRef.value.validateField('newPhone', (valid: any) => {
      if (!valid) {
        proxy.$refs.verifyRef.show();
      }
    });
  };

  /**
   * 发送验证码
   */
  const handleSendCaptcha = (captchaParam: BehaviorCaptchaReq) => {
    if (captchaLoading.value) return;
    formRef.value.validateField('newPhone', (valid: any) => {
      if (!valid) {
        captchaLoading.value = true;
        captchaBtnNameKey.value = 'userCenter.securitySettings.captcha.ing';
        getSmsCaptcha(form.newPhone, captchaParam)
          .then((res) => {
            captchaLoading.value = false;
            captchaDisable.value = true;
            captchaBtnNameKey.value = `${t(
              'userCenter.securitySettings.captcha.get',
            )}(${(captchaTime.value -= 1)}s)`;
            captchaTimer.value = window.setInterval(() => {
              captchaTime.value -= 1;
              captchaBtnNameKey.value = `${t(
                'userCenter.securitySettings.captcha.get',
              )}(${captchaTime.value}s)`;
              if (captchaTime.value <= 0) {
                resetCaptcha();
              }
            }, 1000);
            proxy.$message.success(res.msg);
          })
          .catch(() => {
            resetCaptcha();
            captchaLoading.value = false;
          });
      }
    });
  };

  /**
   * 取消
   */
  const handleCancel = () => {
    visible.value = false;
    formRef.value.resetFields();
    resetCaptcha();
  };

  /**
   * 修改
   */
  const handleUpdate = () => {
    formRef.value.validate((valid: any) => {
      if (!valid) {
        updatePhone({
          newPhone: form.newPhone,
          captcha: form.captcha,
          currentPassword: encryptByRsa(form.currentPassword) || '',
        }).then((res) => {
          handleCancel();
          userStore.getInfo();
          proxy.$message.success(res.msg);
        });
      }
    });
  };

  /**
   * 打开修改对话框
   */
  const toUpdate = () => {
    visible.value = true;
  };
</script>

<template>
  <a-list-item-meta>
    <template #avatar>
      <a-typography-paragraph>
        {{ $t('userCenter.securitySettings.phone.label') }}
      </a-typography-paragraph>
    </template>
    <template #description>
      <div class="tip">
        {{ $t('userCenter.securitySettings.phone.tip') }}
      </div>
      <div class="content">
        <a-typography-paragraph v-if="userStore.phone">
          {{ userStore.phone }}
        </a-typography-paragraph>
        <a-typography-paragraph v-else class="tip">
          {{ $t('userCenter.securitySettings.phone.content') }}
        </a-typography-paragraph>
      </div>
      <div class="operation">
        <a-link
          :title="$t('userCenter.securitySettings.button.update')"
          @click="toUpdate"
        >
          {{ $t('userCenter.securitySettings.button.update') }}
        </a-link>
      </div>
    </template>
  </a-list-item-meta>

  <a-modal
    :title="$t('userCenter.securitySettings.updatePhone.modal.title')"
    :visible="visible"
    :mask-closable="false"
    :esc-to-close="false"
    @ok="handleUpdate"
    @cancel="handleCancel"
  >
    <a-form ref="formRef" :model="form" :rules="rules" size="large">
      <a-form-item
        :label="
          $t('userCenter.securitySettings.updatePhone.form.label.newPhone')
        "
        field="newPhone"
      >
        <a-input
          v-model="form.newPhone"
          :placeholder="
            $t(
              'userCenter.securitySettings.updatePhone.form.placeholder.newPhone',
            )
          "
          allow-clear
        />
      </a-form-item>
      <a-form-item
        :label="
          $t('userCenter.securitySettings.updatePhone.form.label.captcha')
        "
        field="captcha"
      >
        <a-input
          v-model="form.captcha"
          :placeholder="
            $t('userCenter.securitySettings.form.placeholder.captcha')
          "
          :max-length="4"
          allow-clear
          style="width: 80%"
        />
        <a-button
          :loading="captchaLoading"
          type="primary"
          :disabled="captchaDisable"
          class="captcha-btn"
          @click="handleOpenBehaviorCaptcha"
        >
          {{ captchaBtnName }}
        </a-button>
      </a-form-item>
      <a-form-item
        :label="
          $t(
            'userCenter.securitySettings.updatePhone.form.label.currentPassword',
          )
        "
        field="currentPassword"
      >
        <a-input-password
          v-model="form.currentPassword"
          :placeholder="
            $t(
              'userCenter.securitySettings.updatePhone.form.placeholder.currentPassword',
            )
          "
          :max-length="32"
          allow-clear
        />
      </a-form-item>
    </a-form>
    <Verify
      ref="verifyRef"
      :mode="captchaMode"
      :captcha-type="captchaType"
      :img-size="{ width: '330px', height: '155px' }"
      @success="handleSendCaptcha"
    ></Verify>
  </a-modal>
</template>

<style scoped lang="less">
  .captcha-btn {
    margin-left: 5px;
  }
</style>
